#include "window.hpp"
#include "glwrapper.hpp"

#include <GLFW/glfw3.h>
#include <iostream>

GLFWwindow* carbon::C_Window::_window;
int carbon::C_Window::FPS;

// initializes GLFW window
// if `fullscreen` is true, then W and H parameters will be ignored
int carbon::C_Window::initialize(int w, int h, const char* title, bool fullscreen) {
    // open window in fullscreen mode
    if (fullscreen) {
        GLFWmonitor* monitor_p = glfwGetPrimaryMonitor();
        const GLFWvidmode* mode = glfwGetVideoMode(monitor_p);

        _window = glfwCreateWindow(
            mode->width,
            mode->height,
            title,
            monitor_p,
            nullptr);
        glViewport(0, 0, mode->width, mode->height);
    } else {
        _window = glfwCreateWindow(
            w,
            h,
            title,
            nullptr,
            nullptr);
        glViewport(0, 0, w, h);
    }

    if (int result = carbon::C_GLWrappper::checkWindow(_window) != 0) return result;

    carbon::C_GLWrappper::setGlfwMinmaxVer(3, 3);
    carbon::C_GLWrappper::enableForwardCompat();
    carbon::C_GLWrappper::enableCoreProfile();
    carbon::C_GLWrappper::enableMultisampling(4);

    glfwMakeContextCurrent(_window);

    carbon::C_GLWrappper::initializeGlew();

    return 0;
}

void carbon::C_Window::terminate() {
    glfwDestroyWindow(_window);
}

void carbon::C_Window::update() { 
    updateFpsCounter();
    glfwSwapBuffers(_window);
}
bool carbon::C_Window::isOpen() { return !glfwWindowShouldClose(_window); }
void carbon::C_Window::close() { glfwSetWindowShouldClose(_window, GLFW_TRUE); }

// not implemented yet
void carbon::C_Window::setIcon(const char* path) { }

void carbon::C_Window::updateFpsCounter() {
    static double previous_seconds = glfwGetTime();
    static int frame_count;
    double current_seconds = glfwGetTime();
    double elapsed_seconds = current_seconds - previous_seconds;

    if (elapsed_seconds > 0.25) {
        previous_seconds = current_seconds;
        double fps = static_cast<double>(frame_count) / elapsed_seconds;
        FPS = static_cast<int>(fps);
        frame_count = 0;
    }
    frame_count++;
}
